package com.common.pattern.pipeline.config;

import com.common.pattern.pipeline.bo.PipelineContext;
import com.common.pattern.pipeline.utils.ContextHandlerUtil;
import com.common.pattern.pipeline.handler.ContextHandler;
import org.apache.commons.lang3.BooleanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Author: xuxiang
 * @Date: 2023-8-10
 * @Description: 管道执行器
 */
@ConditionalOnClass(ContextHandler.class)
public class PipelineExecutor {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    /**
     * PipelineRouteConfig 中的 pipelineRouteMap
     */
    @Resource
    private Map<Class<? extends PipelineContext>,
            List<? extends ContextHandler<? super PipelineContext>>> pipelineRouteMap;

    @Resource
    private PipelineManualProperty pipelineManualProperty;

    /**
     * 同步处理输入的上下文数据<br/>
     * 如果处理时上下文数据流通到最后一个处理器且最后一个处理器返回 true，则返回 true，否则返回 false
     *
     * @param context 输入的上下文数据
     * @return 处理过程中管道是否畅通，畅通返回 true，不畅通返回 false
     */
    public boolean acceptSync(PipelineContext context) {
        Objects.requireNonNull(context, "上下文数据不能为 null");
        // 拿到context数据类型
        Class<? extends PipelineContext> dataType = context.getClass();
        // 获取数据处理管道list (每一节)
        List<? extends ContextHandler<? super PipelineContext>> pipelineHandlerList = pipelineRouteMap.get(dataType);
        if (CollectionUtils.isEmpty(pipelineHandlerList)) {
            logger.error("{} 的管道为空", dataType.getSimpleName());
            return false;
        }
        // 管道是否畅通
        boolean lastSuccess = true;
        for (ContextHandler<? super PipelineContext> handler : pipelineHandlerList) {
            try {
                lastSuccess = handler.handle(context);
                ContextHandlerUtil.printHandlerMsg(handler, BooleanUtils.isTrue(pipelineManualProperty.getPintLog()));
            } catch (Exception ex) {
                lastSuccess = false;
                logger.error("[{}] 处理异常，handler={}", context.getModelName(), handler.getClass().getSimpleName(), ex);
            }
            // 终止处理
            if (!lastSuccess) {
                break;
            }
        }
        return lastSuccess;
    }

}